<?php
/**
 * 测试签到结束计算
 */

echo "=== 测试签到结束积分计算 ===\n\n";

// 复制 calculatePoints 和 calculatePointsByTimeSlots 函数
function calculatePoints(int $durationMinutes, string $startTime, string $endTime, int $unitMinutes, int $unitPoints, string $rounding, string $timeSlotsJson): int
{
    echo "[CHECKIN] calculatePoints called - duration: {$durationMinutes}, startTime: {$startTime}, endTime: {$endTime}, unitMinutes: {$unitMinutes}, unitPoints: {$unitPoints}\n";
    echo "[CHECKIN] timeSlotsJson: " . $timeSlotsJson . "\n";

    // 如果有时间段配置，优先使用时间段规则
    if (!empty($timeSlotsJson)) {
        $timeSlots = json_decode($timeSlotsJson, true);
        echo "[CHECKIN] Decoded timeSlots: " . json_encode($timeSlots, JSON_UNESCAPED_UNICODE) . "\n";

        if (is_array($timeSlots) && count($timeSlots) > 0) {
            echo "[CHECKIN] Using time slots rule, slots count: " . count($timeSlots) . "\n";
            return calculatePointsByTimeSlots($durationMinutes, $startTime, $endTime, $timeSlots, $unitMinutes, $unitPoints, $rounding);
        } else {
            echo "[CHECKIN] timeSlots is not valid array or empty, using base rule\n";
        }
    } else {
        echo "[CHECKIN] timeSlotsJson is empty, using base rule\n";
    }

    // 使用基础规则：floor(时长 / 单位分钟) × 单位积分
    if ($unitMinutes <= 0) $unitMinutes = 10;
    if ($unitPoints <= 0) $unitPoints = 1;

    // 计算单位数（向下取整，不满1个单位不计算）
    $units = intval(floor($durationMinutes / $unitMinutes));

    // 计算总积分
    $totalPoints = $units * $unitPoints;

    echo "[CHECKIN] Base rule: {$durationMinutes} minutes / {$unitMinutes} = {$units} units × {$unitPoints} points = {$totalPoints} points\n";

    return $totalPoints;
}

function calculatePointsByTimeSlots(int $durationMinutes, string $startTime, string $endTime, array $timeSlots, int $unitMinutes, int $unitPoints, string $rounding): int
{
    echo "[CHECKIN] calculatePointsByTimeSlots called - duration: {$durationMinutes}, startTime: {$startTime}, endTime: {$endTime}\n";
    echo "[CHECKIN] Parameters - unitMinutes: {$unitMinutes}, unitPoints: {$unitPoints}, timeSlots: " . json_encode($timeSlots, JSON_UNESCAPED_UNICODE) . "\n";

    if ($unitMinutes <= 0) $unitMinutes = 10;
    if ($unitPoints <= 0) $unitPoints = 1;

    // 将开始和结束时间转换为时间戳
    $startTimestamp = strtotime($startTime);
    $endTimestamp = strtotime($endTime);

    // 解析时间段配置，转换为分钟数（从当天00:00开始）
    $parsedSlots = [];
    foreach ($timeSlots as $slot) {
        $slotStart = $slot['start'] ?? '';
        $slotEnd = $slot['end'] ?? '';

        if (empty($slotStart) || empty($slotEnd)) continue;

        // 解析时间段的开始和结束时间
        list($sh, $sm) = explode(':', $slotStart);
        list($eh, $em) = explode(':', $slotEnd);

        $slotStartMinutes = intval($sh) * 60 + intval($sm);
        $slotEndMinutes = intval($eh) * 60 + intval($em);
        $pointsPerUnit = intval($slot['points_per_hour'] ?? 1);

        $parsedSlots[] = [
            'start' => $slotStartMinutes,
            'end' => $slotEndMinutes,
            'points_per_unit' => $pointsPerUnit,
            'label' => "{$slotStart}-{$slotEnd}"
        ];
    }

    // 按开始时间排序时间段
    usort($parsedSlots, function($a, $b) {
        return $a['start'] - $b['start'];
    });

    // 将签到时长按分钟拆分，逐分钟计算所属时间段
    $totalPoints = 0;
    $currentTimestamp = $startTimestamp;

    // 用于统计每个时间段的分钟数（用于日志输出）
    $segmentStats = [];

    while ($currentTimestamp < $endTimestamp) {
        // 获取当前时间点的小时和分钟
        $currentHour = intval(date('H', $currentTimestamp));
        $currentMinute = intval(date('i', $currentTimestamp));
        $currentTimeValue = $currentHour * 60 + $currentMinute;

        // 查找当前时间点所属的时间段
        $matchedSlot = null;
        foreach ($parsedSlots as $slot) {
            // 时间段边界：左闭右开 [start, end)
            if ($currentTimeValue >= $slot['start'] && $currentTimeValue < $slot['end']) {
                $matchedSlot = $slot;
                break;
            }
        }

        // 确定当前时间段的积分规则
        if ($matchedSlot !== null) {
            $segmentKey = $matchedSlot['label'];
            $pointsPerUnit = $matchedSlot['points_per_unit'];
        } else {
            $segmentKey = 'base';
            $pointsPerUnit = $unitPoints;
        }

        // 累计该时间段的分钟数
        if (!isset($segmentStats[$segmentKey])) {
            $segmentStats[$segmentKey] = [
                'minutes' => 0,
                'points_per_unit' => $pointsPerUnit
            ];
        }
        $segmentStats[$segmentKey]['minutes']++;

        // 移动到下一分钟
        $currentTimestamp += 60;
    }

    // 根据每个时间段的分钟数计算积分
    foreach ($segmentStats as $segmentKey => $stats) {
        $minutes = $stats['minutes'];
        $pointsPerUnit = $stats['points_per_unit'];

        // 计算单位数（向下取整）
        $units = intval(floor($minutes / $unitMinutes));
        $segmentPoints = $units * $pointsPerUnit;

        $totalPoints += $segmentPoints;

        echo "[CHECKIN] Segment '{$segmentKey}': {$minutes} minutes / {$unitMinutes} = {$units} units × {$pointsPerUnit} points = {$segmentPoints} points\n";
    }

    echo "[CHECKIN] Total points calculated: {$totalPoints} points for {$durationMinutes} minutes\n";

    return $totalPoints;
}


// 固定的测试数据
$startTime = '2025-11-18 07:00:58';
$endTime = '2025-11-18 09:21:08';

// 计算时长
$startTimestamp = strtotime($startTime);
$endTimestamp = strtotime($endTime);
$durationMinutes = intval(($endTimestamp - $startTimestamp) / 60);

echo "开始时间: {$startTime}\n";
echo "结束时间: {$endTime}\n";
echo "时长: {$durationMinutes} 分钟\n\n";

// 获取数据库连接
try {
    // 读取 .env
    function loadDotEnv(string $path): array {
        if (!is_file($path)) return [];
        $vars = [];
        foreach (file($path) as $line) {
            $line = trim($line);
            if ($line === '' || $line[0] === '#') continue;
            $pos = strpos($line, '=');
            if ($pos === false) continue;
            $key = trim(substr($line, 0, $pos));
            $val = trim(substr($line, $pos + 1));
            if ((strlen($val) >= 2) && (($val[0] === '"' && substr($val, -1) === '"') || ($val[0] === "'" && substr($val, -1) === "'"))) {
                $val = substr($val, 1, -1);
            }
            $vars[$key] = $val;
        }
        return $vars;
    }

    $env = loadDotEnv(__DIR__ . '/.env');

    $dbConfig = [
        'host' => $env['DB_MYSQL_HOST'] ?? getenv('DB_MYSQL_HOST') ?? '127.0.0.1',
        'port' => $env['DB_MYSQL_PORT'] ?? getenv('DB_MYSQL_PORT') ?? '3306',
        'database' => $env['DB_MYSQL_DATABASE'] ?? getenv('DB_MYSQL_DATABASE') ?? 'qiandao',
        'username' => $env['DB_MYSQL_USERNAME'] ?? getenv('DB_MYSQL_USERNAME') ?? 'root',
        'password' => $env['DB_MYSQL_PASSWORD'] ?? getenv('DB_MYSQL_PASSWORD') ?? '',
    ];

    $dsn = "mysql:host={$dbConfig['host']};port={$dbConfig['port']};dbname={$dbConfig['database']};charset=utf8mb4";
    $pdo = new PDO($dsn, $dbConfig['username'], $dbConfig['password']);
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

    echo "=== 获取系统配置 ===\n\n";

    // 获取系统配置
    $stmt = $pdo->prepare("SELECT * FROM checkin_setting WHERE store_id = 0 LIMIT 1");
    $stmt->execute();
    $config = $stmt->fetch(PDO::FETCH_ASSOC);

    if (!$config) {
        echo "未找到系统配置，使用默认值\n";
        $config = [
            'unit_minutes' => 10,
            'unit_points' => 1,
            'rounding' => 'floor',
            'time_slots' => '',
        ];
    }

    $unitMinutes = intval($config['unit_minutes']);
    $unitPoints = intval($config['unit_points'] ?? 1);
    $rounding = strval($config['rounding']);
    $timeSlotsJson = strval($config['time_slots'] ?? '');

    echo "单位分钟数: {$unitMinutes}\n";
    echo "单位积分: {$unitPoints}\n";
    echo "取整方式: {$rounding}\n";
    echo "时间段配置: {$timeSlotsJson}\n\n";

    echo "=== 调用 calculatePoints 函数 ===\n\n";

    // 调用 calculatePoints 函数
    $points = calculatePoints($durationMinutes, $startTime, $endTime, $unitMinutes, $unitPoints, $rounding, $timeSlotsJson);

    echo "\n=== 计算结果 ===\n\n";
    echo "计算积分: {$points} 分\n";

    // 解析时间段配置，显示详细信息
    if (!empty($timeSlotsJson)) {
        $timeSlots = json_decode($timeSlotsJson, true);
        if (is_array($timeSlots) && count($timeSlots) > 0) {
            echo "\n=== 时间段配置 ===\n\n";
            foreach ($timeSlots as $slot) {
                echo "  - {$slot['start']} 到 {$slot['end']}: {$slot['points_per_hour']} 分/单位\n";
            }
        }
    }

    echo "\n=== 预期结果 ===\n\n";
    echo "根据重新计算功能，正确结果应该是: 18 分\n";
    echo "实际计算结果: {$points} 分\n";
    
    if ($points == 18) {
        echo "\n✅ 计算正确！\n";
    } else {
        echo "\n❌ 计算错误！差值: " . ($points - 18) . " 分\n";
    }

} catch (PDOException $e) {
    echo "数据库错误: " . $e->getMessage() . "\n";
} catch (Exception $e) {
    echo "错误: " . $e->getMessage() . "\n";
}

